/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package vale.sax;

import vale.sax.io.XmlFileReader;
import java.io.File;
import vale.sax.sintaxis.ValidadorSintaxis;

/**
 *
 * @author juan
 */
public final class Sax implements Runnable {

    private ErrorHandler eh;
    private ContentHandler ch;
    private File xmlFile;
    private ValidadorSintaxis vSintaxis;

    public Sax(ErrorHandler eh, ContentHandler ch, File xmlFile) {
        this.eh = eh;
        this.ch = ch;
        this.xmlFile = xmlFile;
        this.vSintaxis = new ValidadorSintaxis();
    }

    public void run() {
        try {
            String[] xml = XmlFileReader.read(this.xmlFile);
            contenManager(ValidadorSintaxis.START_DOCUMENT, null);
            for (String xmlElement : xml) {
                byte type = vSintaxis.validate(xmlElement);
                this.contenManager(type, xmlElement);
            }
            if (!vSintaxis.isBalanced()) {
                throw new SaxException(SaxException.FATAL_ERROR, "XML not Balanced");
            }
            contenManager(ValidadorSintaxis.END_DOCUMENT, null);
        } catch (SaxException ex) {
            errorManager(ex);
        }
    }

    private void contenManager(byte type, String read) {
        if (read == null) {
            read = "";
        }
        try {
            switch (type) {
                case ValidadorSintaxis.XML_SYNTAX_ERROR:
                    throw new SaxException(SaxException.ERROR, "Unknow Elemet Type: " + read);
                case ValidadorSintaxis.START_DOCUMENT:
                    this.ch.startDocument();
                    break;
                case ValidadorSintaxis.DOC_INFO:
                    this.ch.DocInfo(read);
                    break;
                case ValidadorSintaxis.DTD_DATA:
                    this.ch.DtdData(read);
                case ValidadorSintaxis.START_ELEMENT:
                    this.ch.startElement(read);
                    break;
                case ValidadorSintaxis.INSERT_CONTENT:
                    this.ch.insertContent(read);
                    break;
                case ValidadorSintaxis.END_ELEMENT:
                    this.ch.endElement(read);
                    break;
                case ValidadorSintaxis.AUTO_CLOSE_ELEMENT:
                    this.ch.startElement(read);
                    this.ch.endElement(read);
                    break;
                case ValidadorSintaxis.COMMENT:
                    break;
                case ValidadorSintaxis.END_DOCUMENT:
                    this.ch.endDocument();
                    break;
                default:
                    String msg= "In Element:" + read +
                            "\nValue Return: " + String.valueOf(type);
                    throw new SaxException(SaxException.FATAL_ERROR, msg);
            }
        } catch (SaxException ex) {
            errorManager(ex);
        }
    }

    private void errorManager(SaxException ex) {
        if (ex != null) {
            switch (ex.getType()) {
                case SaxException.ERROR:
                    this.eh.error(ex);
                    break;
                case SaxException.FATAL_ERROR:
                    this.eh.fatalError(ex);
                    break;
                case SaxException.WARNING:
                    this.eh.warning(ex);
                    break;
                default:
                    this.eh.fatalError(new SaxException(SaxException.FATAL_ERROR, "Unknow Type SaxException"));
                    break;
            }
        } else {
            this.eh.fatalError(new SaxException(SaxException.FATAL_ERROR, "NullPointer SaxException"));
        }
    }
}
